import random
from pathlib import Path
from typing import List, Optional

from PyQt5.QtCore import Qt, QTimer, QFileSystemWatcher
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget
from .detector import detect_people_in_image


SUPPORTED_EXTS = {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".webp"}


def list_image_files(root: Path) -> List[Path]:
    files: List[Path] = []
    if not root.exists():
        return files
    for p in root.rglob("*"):
        if p.is_file() and p.suffix.lower() in SUPPORTED_EXTS:
            files.append(p)
    return files


class PhotoSlideshow(QWidget):
    def __init__(self, image_dir: Path, interval_ms: int = 5000, shuffle: bool = True, people_weight: float = 2.0, enable_people_priority: bool = False) -> None:
        super().__init__()
        self.image_dir = image_dir
        self.interval_ms = max(1000, interval_ms)
        self.shuffle = shuffle
        self.enable_people_priority = enable_people_priority
        self.people_weight = max(1.0, float(people_weight))

        self._images: List[Path] = list_image_files(self.image_dir)
        if self.shuffle:
            random.shuffle(self._images)
        self._index: int = -1

        # 预计算人物优先权重（轻量同步扫描，失败不影响）
        self._weights: List[float] = []
        if self.enable_people_priority and self._images:
            for p in self._images:
                has_people = detect_people_in_image(p)
                self._weights.append(self.people_weight if has_people else 1.0)
        else:
            self._weights = [1.0 for _ in self._images]

        self._label = QLabel("正在加载图片...")
        self._label.setAlignment(Qt.AlignCenter)
        self._label.setStyleSheet(
            """
            QLabel { background-color: #000; color: #D7E0EA; font-size: 24px; }
            """
        )

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._label)

        self._timer = QTimer(self)
        self._timer.setInterval(self.interval_ms)
        self._timer.timeout.connect(self.show_next)

        # 设置文件夹监控
        self._file_watcher = QFileSystemWatcher(self)
        self._file_watcher.addPath(str(self.image_dir))
        self._file_watcher.directoryChanged.connect(self._on_directory_changed)

        # 立即显示第一张
        self.show_next()
        self._timer.start()

    def resizeEvent(self, event):  # noqa: N802 (qt signature)
        super().resizeEvent(event)
        self._render_current()

    def _render_current(self) -> None:
        if not self._images or self._index < 0:
            self._label.setText("未找到图片")
            return
        img = self._images[self._index]
        pix = QPixmap(str(img))
        if pix.isNull():
            self._label.setText(f"加载失败: {img.name}")
            return
        scaled = pix.scaled(self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self._label.setPixmap(scaled)

    def show_next(self) -> None:
        if not self._images:
            self._label.setText("未找到图片")
            return
        if self.enable_people_priority and self._images:
            # 使用权重抽样选择下一张
            try:
                next_img = random.choices(self._images, weights=self._weights, k=1)[0]
                self._index = self._images.index(next_img)
            except Exception:
                self._index = (self._index + 1) % len(self._images)
        else:
            self._index = (self._index + 1) % len(self._images)
            if self.shuffle and self._index == 0:
                random.shuffle(self._images)
        self._render_current()

    def _on_directory_changed(self, path: str) -> None:
        """当文件夹发生变化时重新扫描图片列表"""
        print(f"检测到文件夹变化: {path}")
        old_count = len(self._images)
        self._images = list_image_files(self.image_dir)
        new_count = len(self._images)
        
        if new_count > old_count:
            print(f"发现 {new_count - old_count} 张新图片，总共 {new_count} 张")
            # 重新计算权重
            if self.enable_people_priority and self._images:
                self._weights = []
                for p in self._images:
                    has_people = detect_people_in_image(p)
                    self._weights.append(self.people_weight if has_people else 1.0)
            else:
                self._weights = [1.0 for _ in self._images]
            
            # 如果启用了随机播放，重新打乱列表
            if self.shuffle:
                random.shuffle(self._images)
        elif new_count < old_count:
            print(f"删除了 {old_count - new_count} 张图片，剩余 {new_count} 张")
            # 重新计算权重
            if self.enable_people_priority and self._images:
                self._weights = []
                for p in self._images:
                    has_people = detect_people_in_image(p)
                    self._weights.append(self.people_weight if has_people else 1.0)
            else:
                self._weights = [1.0 for _ in self._images]
        
        # 如果当前索引超出范围，重置索引
        if self._images and self._index >= len(self._images):
            self._index = 0


